package com.czk.netty.netty.websocket.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

/**
 * websocket长连接开发
 *
 * @Author:ChenZhangKun
 * @Date: 2021/1/19 20:18
 */
public class MyServer {
    public static void main(String[] args) throws InterruptedException {
        // 创建线程组
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workGroup = new NioEventLoopGroup();
        // 服务器
        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(bossGroup, workGroup)
                .channel(NioServerSocketChannel.class)
                .handler(new LoggingHandler(LogLevel.INFO))
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        ChannelPipeline pipeline = socketChannel.pipeline();
                        // 添加处理器 http编码和解码器
                        pipeline.addLast(new HttpServerCodec());
                        // 是以块的方式写，添加chunkWriteHandler处理器
                        pipeline.addLast(new ChunkedWriteHandler());
                        /**
                         * http数据在传输过程中是分段的，需要聚合
                         */
                        pipeline.addLast(new HttpObjectAggregator(8192));
                        /**
                         * 对于websocket数据是以帧的形式传递的
                         * ws://localhost:7001/hello 表示请求的url
                         * WebSocketServerProtocolHandler核心功能是江http协议升级为ws协议，保持长连接,通过状态码101切换的
                         */
                        pipeline.addLast(new WebSocketServerProtocolHandler("/hello"));
                        // 自定义handler处理业务
                        pipeline.addLast(new MyWebSocketFrameHandler());
                    }
                });
        System.out.println("netty 服务器启动了");
        ChannelFuture channelFuture = null;
        try {
            channelFuture = bootstrap.bind(7001).sync();

        } catch (Exception ex) {
            channelFuture.channel().closeFuture().sync();
        }
    }
}
